package org.gruposp2p.proyectokarma.gwt.client.ui;

import java.util.Set;
import org.gruposp2p.proyectokarma.gwt.client.domain.Peer;
import org.gruposp2p.proyectokarma.gwt.client.domain.Role;
import org.gruposp2p.proyectokarma.gwt.client.domain.Role.RoleType;
import org.gruposp2p.proyectokarma.gwt.client.event.EventBusManager;
import org.gruposp2p.proyectokarma.gwt.client.event.LoginEvent;
import org.gruposp2p.proyectokarma.gwt.client.ui.document.EditorPanel;
import org.gruposp2p.proyectokarma.gwt.client.ui.user.CreateUserDialog;
import org.gruposp2p.proyectokarma.gwt.client.util.RequestHelper;
import org.gruposp2p.proyectokarma.gwt.client.util.ServerPaths;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.Widget;
import com.allen_sauer.gwt.log.client.Log;

public class TopPanel extends Composite implements LoginEvent.Handler {

    private static TopPanelUiBinder uiBinder = GWT
                    .create(TopPanelUiBinder.class);
    interface TopPanelUiBinder extends UiBinder<Widget, TopPanel> { }
    
    public static String HISTORY_SEARCH_USER      = "#searchUser";
    public static String HISTORY_CREATE_USER      = "#createUser";
    public static String HISTORY_SEARCH_DOCUMENTS = "#searchDocuments";
    public static String HISTORY_CREATE_DOCUMENTS = "#createDocuments";
    public static String HISTORY_SEARCH_COMMENTS  = "#searchComments";
    public static String HISTORY_SEARCH_VOTES     = "#searchVotes";
    public static String HISTORY_SEND_MESSAGES    = "#sendMessages";
    public static String HISTORY_SEARCH_MESSAGES  = "#searchMessages";
    public static String HISTORY_LOGIN            = "#login";
    public static String HISTORY_START            = "#start";
    public static String HISTORY_ADMIN            = "#admin";
    public static String HISTORY_TAG              = "#tag";

    @UiField HorizontalPanel horizontalPanel;
    @UiField MenuBar topMenuBar;
    @UiField MenuItem usersMenuItem;
    @UiField MenuItem documentsMenuItem;
    @UiField MenuItem votesMenuItem;
    @UiField MenuItem searchMessagesMenuItem;
    @UiField MenuItem sendMessagesMenuItem;
    @UiField MenuItem loginMenuItem;
    @UiField MenuItem logoutMenuItem;
    @UiField MenuItem searchUserMenuItem;
    @UiField MenuItem searchDocumentMenuItem;
    @UiField MenuItem createDocumentMenuItem;
    @UiField MenuItem searchCommentMenuItem;
    @UiField MenuItem createCommentMenuItem;
    @UiField MenuItem searchVoteMenuItem;
    @UiField MenuItem adminMenuItem;
    @UiField MenuItem uploadDocumentMenuItem;
    @UiField MenuItem createUserMenuItem;
    
    private EditorPanel editorDialog;

    public TopPanel() {
         initWidget(uiBinder.createAndBindUi(this));
         EventBusManager.getInstance().registerToLoginEvent(this);
         searchUserMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEARCH_USER));
         createUserMenuItem.setCommand(new CreateUserCommand());
         searchDocumentMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEARCH_DOCUMENTS));
         createDocumentMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_CREATE_DOCUMENTS));
         searchCommentMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEARCH_COMMENTS));
         searchVoteMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEARCH_VOTES));
         loginMenuItem.setCommand(new LoginCommand());
         logoutMenuItem.setVisible(false);
         logoutMenuItem.setCommand(new LogoutCommand());
         uploadDocumentMenuItem.setCommand(new UploadFileCommand());
         sendMessagesMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEND_MESSAGES));
         searchMessagesMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_SEARCH_MESSAGES));
         adminMenuItem.setCommand(new MenuCommand(TopPanel.HISTORY_ADMIN));
    }
    
    private class MenuCommand implements Command {
        final String token;
        public MenuCommand(String token) {
        	this.token = token;
        }
        @Override
        public void execute() {
        	History.newItem(token);
        	History.fireCurrentHistoryState();
        }
    }  
    
    private class UploadFileCommand implements Command {
        public UploadFileCommand() {}
        @Override
        public void execute() {
            UploadDocumentDialog uploadFileDialog = new UploadDocumentDialog();
            uploadFileDialog.show();
        }
    }
    
    private class LoginCommand implements Command {
        public LoginCommand() {}
        @Override
        public void execute() {
        	LoginDialog loginDialog = new LoginDialog ();
        	loginDialog.show();
        }
    }
    
    private class CreateUserCommand implements Command {
        public CreateUserCommand() {}
        @Override
        public void execute() {
        	CreateUserDialog createUserDialog = new CreateUserDialog ();
        	createUserDialog.show();
        }
    }
    
    private class LogoutCommand implements Command {
        public LogoutCommand() {}
        @Override
        public void execute() {
        	RequestHelper.doGet(ServerPaths.getLogoutPath(), 
        			new LogoutRequestCallback());
        }
    }

	@Override
	public void onLoginEvent(LoginEvent event) {
		switch (event.eventType) {
			case LOGIN:
		        logoutMenuItem.setVisible(true);
				loginMenuItem.setText(event.peer.getUsername());
				loginMenuItem.setCommand(null);
				break;
			case LOGOUT:
		        logoutMenuItem.setVisible(false);
				loginMenuItem.setText("Login");
				loginMenuItem.setCommand(new LoginCommand());
				break;
		}
	}  

	private void setMenuBar (Peer peer) {
		Set<Role> roles = peer.getPeerRole();
		RoleType roleType = null;
		for (Role role: roles) {
			switch (role.getAuthority()) {
				case ROLE_SUPERADMIN:
					roleType = RoleType.ROLE_SUPERADMIN;
					break;
				case ROLE_ADMIN:
					if (!RoleType.ROLE_SUPERADMIN.equals(roleType)) 
						roleType = RoleType.ROLE_ADMIN;
					break;
				case ROLE_USER:
					if (!(RoleType.ROLE_SUPERADMIN.equals(roleType)
							||RoleType.ROLE_ADMIN.equals(roleType))) 
					roleType = RoleType.ROLE_USER;
					break;					
			}	
		}
		setMenuBar (roleType);		
	}
	
	
	public void setMenuBar (RoleType roleType) {
		switch (roleType) {
			case ROLE_SUPERADMIN:
				setSuperAdminBar();
				break;
			case ROLE_ADMIN:
				setAdminBar();
				break;
			case ROLE_USER:
				setUserBar();
				break;
		}
		
	}
	
	public void setSuperAdminBar () {
		adminMenuItem.setVisible(true);
		documentsMenuItem.setVisible(true);
	}
	
	public void setAdminBar () {
		adminMenuItem.setVisible(false);
		documentsMenuItem.setVisible(true);
	}
	
	public void setUserBar () {
		adminMenuItem.setVisible(false);
		documentsMenuItem.setVisible(false);
	}
	
	private void setVisitorBar () {}
	
    private class LogoutRequestCallback implements RequestCallback {

        @Override
    	public void onError(Request request, Throwable exception) {
        	new ErrorDialog().show("Exception", exception.getMessage());
        	Log.error(exception.getMessage());
    	}

        @Override
    	public void onResponseReceived(Request request, Response response) {
			Log.debug("StatusCode: " + response.getStatusCode() + 
					", Response Text: " + response.getText());

    		if (response.getStatusCode() == Response.SC_OK) {
    			LoginEvent loginEvent = new LoginEvent (LoginEvent.EventType.LOGOUT);
                EventBusManager.getInstance().fireEvent(loginEvent);
    		} else {
    			new ErrorDialog().show("ERROR", "Error (" + response.getStatusCode() + "," 
    					+ response.getStatusText() + ")]");
    		}
    	}

    }
	
}